package com.echatim;


import com.echatim.form.SocketHideProtocolMessage;
import com.google.common.io.Files;
import com.utils.Beans;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.*;

/**
 *  将后端工程的DTO 转成cpp 格式的model.
 * */
public class CPPDTOGenerator {
    //获取项目目录
    private static final String projectPath = System.getProperty("user.dir") + File.separator + "server-tools";
    //项目基础包
    private static final String dtoPackage = "com.echatim.dto";
    private static final String formPackage = "com.echatim.form";
    private static final String DirName = "dto_json"; //


    private static String bashCommand(String command) {
        Process process = null;
        String stringBack = null;
        List<String> processList = new ArrayList<String>();
        try {
            process = Runtime.getRuntime().exec(command);
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = "";
            while ((line = input.readLine()) != null) {
                processList.add(line);
            }
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (String line : processList) {
            stringBack += line;
            stringBack +="\n";
        }
        return stringBack;
    }

    private static void genJson(String dtoPackage, String outDir, boolean isDTO) {
        //反射工具包，指明扫描路径
        Reflections reflections = new Reflections(dtoPackage,
                Collections.singletonList(
                        new SubTypesScanner(false)));
        if(isDTO){
            Set<Class<? extends Object>> classListDto = reflections.getSubTypesOf(Object.class);
            classListDto.forEach(v->{
                try {
                    Map<String, Object> jsonDto = new HashMap<>();
                    jsonDto.put(v.getSimpleName(), v.newInstance());
                    System.out.println("class instance json:" + Beans.json(jsonDto));
                    Files.write(Beans.json(jsonDto).getBytes(Charset.defaultCharset()),
                            new File(outDir + File.separator  +  v.getSimpleName() + ".json"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        else {
            Set<Class<? extends SocketHideProtocolMessage>> classListForm = reflections.getSubTypesOf(SocketHideProtocolMessage.class);
            classListForm.forEach(v->{
                try {
                    Map<String, Object> jsonDto = new HashMap<>();
                    jsonDto.put(v.getSimpleName(), v.newInstance());
                    System.out.println("class instance json:" + Beans.json(jsonDto));
                    Files.write(Beans.json(jsonDto).getBytes(Charset.defaultCharset()),
                            new File(outDir + File.separator  +  v.getSimpleName() + ".json"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }


    public static void main(String[] args) throws IOException, InterruptedException {
        String outDir = projectPath + File.separator + "target" + File.separator +  DirName;
        if(!new File(outDir).exists()){
            new File(outDir).mkdirs();
        }
        // 生成dto json
        genJson(dtoPackage, outDir, true);
        // 生成form json
//        genJson(formPackage, outDir, false);

        // 使用python 工具将json文件生成cpp model.
        String pythonToolsBase = projectPath + File.separator + "src" + File.separator + "main" + File.separator + "python";
        String pythonToolName = "json2cppCmd.py";
        String bashCmdStr = "python3 " + pythonToolsBase + File.separator + pythonToolName;
        String pythonResult = bashCommand(bashCmdStr);
        System.out.println(pythonResult);
        System.out.println("---- Transfer DTO to cpp model end. ---");
    }
}
